package com.example.buletooth_spp;

import static android.bluetooth.BluetoothDevice.BOND_BONDED;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.ParcelUuid;
import android.widget.ArrayAdapter;
//import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import java.io.IOException;
import java.io.OutputStream;
import java.io.InputStream;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 蓝牙适配器
 */
public class BlueToothSelectTools {

    public static final int REQUEST_CODE = 0;

    //适配器对象
    private BluetoothAdapter mAdapter = null;

    //父活动对象
    protected AppCompatActivity activity = null;

    //设备列表
    private Set<BluetoothDevice> devices = null;

    //设备信息选项对话框
    private AlertDialog.Builder builder = null;
    private List<String> devicesStringList = null;
    private ArrayAdapter<String> adapter = null;

    //配对的设备
    private BluetoothDevice pairDevice = null;
    private boolean connectFlag = false;

    //蓝牙套接字
    private BluetoothSocket socket = null;

    //数据流
    protected OutputStream outputStream = null;
    protected InputStream inputStream = null;

    //信号
    public static final String CONNECT_ENABLE = "com.example.buletooth_spp.BlueTooth.CONNECT_ENABLE";
    public static final String CONNECT_DISABLE = "com.example.buletooth_spp.BlueTooth.CONNECT_DISABLE";

    //配对设备
    @SuppressLint("MissingPermission")
    private final BroadcastReceiver pairReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            //设备配对状态变化
            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
                int previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

                String deviceItemInfo = deviceToInfo(device);

                // 配对成功
                if (bondState == BluetoothDevice.BOND_BONDED) {
                    pairDevice = device;
                    PrintTip.printInfo(activity, "绑定成功: " + deviceItemInfo);
                    //绑定成功，开始建立连接
                    BlueToothSelectTools.this.connectDevice();
                } else if (bondState == BluetoothDevice.BOND_NONE && previousBondState == BluetoothDevice.BOND_BONDED) { // 配对失败或取消配对
                    pairDevice = null;
                    //绑定成功/取消，断开连接
                    BlueToothSelectTools.this.disConnect();
                    PrintTip.printInfo(activity, "配对失败");
                }
            }
        }
    };

    // BroadcastReceiver 处理蓝牙搜索的结果
    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        //发现新的蓝牙设备，更新设备列表
        @SuppressLint("MissingPermission")
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // 获取发现的设备
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null) {
                    devices.add(device);
                    //更新选项
                    updateItems();
                }
            }
        }
    };

    protected void onDestroy() {
        //super.onDestroy();
        // 取消注册 BroadcastReceiver
        this.activity.unregisterReceiver(receiver);
        this.activity.unregisterReceiver(pairReceiver);
        this.disConnect();
    }

    @SuppressLint("MissingPermission")
    private void connectDevice() {
        if (this.pairDevice == null)
            return;

        try {
            //检查UUID是否是SPP通信
            socket = this.pairDevice.createRfcommSocketToServiceRecord(
                    UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
            socket.connect();

            //判断连接是否成功
            if(socket == null || !socket.isConnected())
            {
                connectFlag = false;

                PrintTip.printInfo(
                        this.activity, "建立连接失败，请重新连接");
                return;
            }

            //获取输入输出流
            this.outputStream = socket.getOutputStream();
            this.inputStream = socket.getInputStream();
            connectFlag = true;

            // 发送连接成功信号
            Intent intent = new Intent(CONNECT_ENABLE);
            this.activity.sendBroadcast(intent);

            //连接成功
            PrintTip.printInfo(this.activity, "建立连接成功");
        } catch (IOException e) {
            //e.printStackTrace();
            // 处理连接错误
            PrintTip.printInfo(
                    this.activity, "建立连接失败，请尝试重新连接，错误原因:" + e.toString());

            connectFlag = false;
//            PrintTip.printInfo(
//                    this.activity, "建立连接失败，请重新连接");
        }
    }

    private void disConnect() {
        if (socket == null)
            return;

        try {
            socket.close();
            this.outputStream.close();
            this.inputStream.close();
            socket = null;
        } catch (IOException e) {
            // 处理连接错误
            PrintTip.printInfo(
                    this.activity, "关闭连接失败，错误原因:" + e.toString());
        }

        // 发送关闭连接信号
        Intent intent = new Intent(CONNECT_DISABLE);
        this.activity.sendBroadcast(intent);
        connectFlag = false;
    }

    @SuppressLint("MissingPermission")
    public BlueToothSelectTools(AppCompatActivity activity) {
        //获取蓝牙对象
        this.mAdapter = BluetoothAdapter.getDefaultAdapter();
        this.activity = activity;
        // 创建构造器
        this.builder = new AlertDialog.Builder(this.activity);
        //菜单选项提示
        this.devicesStringList = new ArrayList<>();
        //数据关联器
        this.adapter = new ArrayAdapter<>(this.activity, android.R.layout.simple_list_item_1, devicesStringList);
        //搜索到的设备
        this.devices = new HashSet<>();

        //不支持蓝牙
        if (this.mAdapter == null) {
            new AlertDialog.Builder(activity)
                    .setTitle("警告")
                    .setMessage("该设备蓝牙不可用")
                    .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int which) {
                            // 确定按钮的点击事件
                            activity.finish();
                        }
                    })
                    .show();
        } else {
            if (!this.mAdapter.isEnabled())      //蓝牙未开启
            {
                //申请开启蓝牙
                this.getBlueToothStates();
            }
        }

        // 注册接收器接收蓝牙搜索到的设备信息
        IntentFilter intent = new IntentFilter();
        intent.addAction(BluetoothDevice.ACTION_FOUND); // 用BroadcastReceiver来取得搜索结果
        intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        intent.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        this.activity.registerReceiver(this.receiver, intent);

        // 注册接收器接收蓝牙配对的信息
        // 注册配对广播接收器
        IntentFilter bondFilter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        this.activity.registerReceiver(this.pairReceiver, bondFilter);

        //蓝牙开始监听
        if (mAdapter.isEnabled() && !mAdapter.isDiscovering()) {
            mAdapter.startDiscovery();
        }
//        // 注册 BroadcastReceiver，发现新的蓝牙设备
//        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
//        activity.registerReceiver(receiver, filter);
    }

    @SuppressLint("MissingPermission")
    private void updateItems() {
        // 填充设备数据并刷新适配器
        devicesStringList.clear();  // 清除原有数据
        for (BluetoothDevice device : devices) {
            String deviceInfo = this.deviceToInfo(device);
            devicesStringList.add(deviceInfo);
        }

        // 通知适配器数据已更新
        adapter.notifyDataSetChanged();
    }

    @SuppressLint("MissingPermission")
    public void connect() {
        this.builder.setTitle("选择可用的蓝牙设备");

        this.updateItems();

        this.builder.setAdapter(this.adapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String deviceItemInfo = devicesStringList.get(which);

                BluetoothDevice selectDevice = infoToDevice(deviceItemInfo);

                //没有找到对应设备
                if(selectDevice == null)
                {
                    PrintTip.printInfo(activity, "未找到设备或已绑定:" + deviceItemInfo);
                    return;
                }

                int bondState = selectDevice.getBondState();
                //已绑定
                if(bondState == BluetoothDevice.BOND_BONDED)
                {
                    pairDevice = selectDevice;
                    connectDevice();
                }
                else if (bondState == BluetoothDevice.BOND_NONE)//未绑定
                {
                    bluetoothBoundDevice(selectDevice);
                }
            }
        });

        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // 不进行操作
            }
        });

        // 显示dialog
        builder.create().show();
    }

    @SuppressLint("MissingPermission")
    private void bluetoothBoundDevice(BluetoothDevice device) {
        //申请绑定
        int bondState = device.getBondState();

        if (bondState == BluetoothDevice.BOND_NONE) {              //未绑定绑定
            device.createBond();
        }
        else if (bondState == BluetoothDevice.BOND_BONDED)        //已绑定进行连接
        {
            this.connectDevice();
        }
//        else if (bondState == BluetoothDevice.BOND_BONDED)       //绑定解绑
//        {
//            Method removeBondMethod = null;
//            try {
//                removeBondMethod = device.getClass().getMethod("removeBond", (Class[]) null);
//                removeBondMethod.invoke(device);
//            } catch (Exception e) {
//
//                PrintTip.printInfo(activity, e.toString());
//            }
//        }
    }
//    @SuppressLint("MissingPermission")
//    private void bluetoothUnBoundDevice(String deviceAddress){
//
//        //获取所有绑定的设备
//        Set<BluetoothDevice> pairedDevices = this.mAdapter.getBondedDevices();
//
//        //找到需要解绑的设备
//        BluetoothDevice deviceToUnpair = null;
//        for (BluetoothDevice device : pairedDevices) {
//            if (device.getAddress().equals(deviceAddress)) { // 设备的MAC地址
//                deviceToUnpair = device;
//                break;
//            }
//        }
//
//        //判断是否找到
//        try {
//            if (deviceToUnpair != null) {
//                Method removeBondMethod = deviceToUnpair.getClass().getMethod("removeBond", (Class[]) null);
//                removeBondMethod.invoke(deviceToUnpair);
//                //PrintTip.printInfo(activity, "已解除绑定设备:" + );
//            }
//        }
//        catch (Exception e)
//        {
//            PrintTip.printInfo(activity, e.toString());
//        }
//    }
    @SuppressLint("MissingPermission")
    private String deviceToInfo(BluetoothDevice device) {
        String deviceName = device.getName();
        String deviceAddress = device.getAddress();
        String deviceState = (device.getBondState() == BOND_BONDED ? "(已绑定)" : "");

        return deviceName + " (" + deviceAddress + ")" + deviceState;
    }

    private BluetoothDevice infoToDevice(String deviceItemInfo) {
        // 正则表达式，用于匹配圆括号中的内容
        String regex = "\\(([^)]+)\\)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(deviceItemInfo);

        //获取到地址
        if (matcher.find()) {
            String deviceAddress = matcher.group(1);  // 获取圆括号内的内容
            return this.mAdapter.getRemoteDevice(deviceAddress);
        }

        return null;
    }

    //检查设备的 UUID 以确定是否支持 SPP
    @SuppressLint("MissingPermission")
    public static boolean checkedDeviceUUID(BluetoothDevice device) {
        boolean flag = false;

        ParcelUuid[] uuids = device.getUuids();

        if (uuids == null)
            return false;

        for (ParcelUuid uuid : uuids) {
            // 是否是 支持 SPP 的设备
            if (uuid.getUuid().equals(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"))) {
                flag = true;
            }
        }

        return flag;
    }

    /**
     * 判断设备是否支持蓝牙
     *
     * @return false表示不支持，true支持
     */
    public boolean isSupportBlueTooth() {
//        //获取蓝牙对象
//        this.mAdapter = BluetoothAdapter.getDefaultAdapter();

        return this.mAdapter != null;
    }

    /**
     * 判断蓝牙状态
     *
     * @return true打开，false关闭
     */
    public boolean getBlueToothStates() {
        //断言提示蓝牙不可用
        assert (mAdapter != null);

        return this.mAdapter.isEnabled();
    }


   /**
     * 申请打开蓝牙
     *
     * @param activity    主窗口
     * @param requestCode REQUEST_CODE 0
     */
    public void turnOnBlueTooth(Activity activity, int requestCode) {
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

        try {
            activity.startActivityForResult(intent, requestCode);
        } catch (SecurityException e) {
            throw new RuntimeException(e);
        }
        //return this.mAdapter.enable(); // 开启蓝牙
    }

    /**
     * 申请关闭蓝牙
     */
    public void turnOffBlueTooth() {
        try {
            this.mAdapter.disable();
        } catch (SecurityException e) {
            throw new RuntimeException(e);
        }
    }
}
